home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / Ang261Lib.lha / src / save.c < prev    next >
C/C++ Source or Header  |  1994-10-22  |  48KB  |  1,879 lines

  1. /*
  2.  * save.c: save and restore games and monster memory info 
  3.  *
  4.  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke 
  5.  *
  6.  * This software may be copied and distributed for educational, research, and
  7.  * not for profit purposes provided that this copyright and statement are
  8.  * included in all such copies. 
  9.  */
  10.  
  11. #include <stdio.h>
  12.  
  13. #include "constant.h"
  14. #include "config.h"
  15. #include "types.h"
  16. #include "externs.h"
  17. #include "monster.h"
  18.  
  19. #ifndef USG
  20. /* stuff only needed for Berkeley UNIX */
  21. #include <sys/types.h>
  22. #include <sys/file.h>
  23. #include <sys/param.h>
  24. #endif
  25.  
  26. #ifdef USG
  27. #ifndef ATARIST_MWC
  28. #include <string.h>
  29. #include <fcntl.h>
  30. #else
  31. #include "string.h"
  32. #endif
  33. #else
  34. #include <strings.h>
  35. #endif
  36.  
  37. #ifdef __MINT__
  38. #include <stat.h>        /* chmod() */
  39. #endif
  40.  
  41. /* Lets do all prototypes correctly.... -CWS */
  42. #ifndef NO_LINT_ARGS
  43. static int sv_write();
  44. static void wr_byte();
  45. static void wr_short();
  46. static void wr_long();
  47. static void wr_bytes();
  48. static void wr_string();
  49. static void wr_shorts();
  50. static void wr_item();
  51. static void wr_monster();
  52. static void rd_byte();
  53. static void rd_short();
  54. static void rd_long();
  55. static void rd_bytes();
  56. static void rd_string();
  57. static void rd_shorts();
  58. static void rd_item();
  59. static void rd_monster();
  60. #endif
  61.  
  62. #if !defined(ATARIST_MWC)
  63. #ifdef MAC
  64. #include <time.h>
  65. #else
  66. long time();
  67.  
  68. #endif
  69. #else
  70. char *malloc();
  71.  
  72. #endif
  73.  
  74. #ifndef SET_UID
  75. #include <sys/stat.h>
  76. #endif
  77.  
  78. /*
  79.  * these are used for the save file, to avoid having to pass them to every
  80.  * procedure 
  81.  */
  82. static FILE        *fileptr;
  83. static int8u        xor_byte;
  84. static int          from_savefile; /* can overwrite old savefile when save */
  85. static int32u       start_time;       /* time that play started */
  86. static int8u        version_maj, version_min, patch_level;
  87.  
  88. /*
  89.  * This save package was brought to by            -JWT- and
  90.  * RAK- and has been completely rewritten for UNIX by    -JEW-  
  91.  */
  92. /* and has been completely rewritten again by     -CJS-     */
  93. /* and completely rewritten again! for portability by -JEW- */
  94.  
  95.  
  96. static char *
  97. basename(a)
  98. char *a;
  99. {
  100.     char *b;
  101.     char *strrchr();
  102.  
  103.     if ((b = strrchr(a, (int)'/')) == (char *)0)
  104.     return a;
  105.     return b;
  106. }
  107.  
  108. static void 
  109. wr_unique(item)
  110. register struct unique_mon *item;
  111. {
  112.     wr_long((int32u) item->exist);
  113.     wr_long((int32u) item->dead);
  114. }
  115.  
  116. static void 
  117. rd_unique(item)
  118. register struct unique_mon *item;
  119. {
  120.     rd_long((int32u *) & item->exist);
  121.     rd_long((int32u *) & item->dead);
  122. }
  123.  
  124.  
  125. static int 
  126. sv_write()
  127. {
  128.     int32u              l;
  129.     register int        i, j;
  130.     int                 count;
  131.     int8u               char_tmp, prev_char;
  132.     register cave_type   *c_ptr;
  133.     register recall_type *r_ptr;
  134.     struct stats         *s_ptr;
  135.  
  136. #ifdef MSDOS
  137.     inven_type           *t_ptr;
  138.  
  139. #endif
  140.     register struct flags *f_ptr;
  141.     store_type  *st_ptr;
  142.     struct misc *m_ptr;
  143.  
  144. /* clear the death flag when creating a HANGUP save file, so that player can
  145.  * see tombstone when restart 
  146.  */
  147.  
  148.     if (eof_flag)
  149.     death = FALSE;
  150.  
  151.     l = 0;
  152.     if (find_cut)
  153.     l |= 1;
  154.     if (find_examine)
  155.     l |= 2;
  156.     if (find_prself)
  157.     l |= 4;
  158.     if (find_bound)
  159.     l |= 8;
  160.     if (prompt_carry_flag)
  161.     l |= 16;
  162.     if (rogue_like_commands)
  163.     l |= 32;
  164.     if (show_weight_flag)
  165.     l |= 64;
  166.     if (highlight_seams)
  167.     l |= 128;
  168.     if (find_ignore_doors)
  169.     l |= 0x100L;
  170.     if (no_haggle_flag)
  171.     l |= 0x200L; 
  172.     if (!carry_query_flag)
  173.     l |= 0x400L;
  174.     if (unfelt)
  175.     l |= 0x0001000L;
  176.     if (delay_spd > 10)
  177.     delay_spd = 10;        /* bounds for delay_speed -CWS */
  178.     if (delay_spd < 0)
  179.     delay_spd = 0;
  180.     l |= ((delay_spd & 0xf) << 13);
  181.     l |= ((hitpoint_warn & 0xf) << 17);
  182.     if (plain_descriptions)    /* don't do "black Mushroom of Curing" -CWS */
  183.     l |= 0x00400000L;
  184.     if (show_equip_weight_flag)
  185.     l |= 0x00800000L;
  186.     if (feeling > 10)
  187.     feeling = 0;        /* bounds for level feelings -CWS */
  188.     if (feeling < 0)
  189.     feeling = 0;
  190.     l |= ((feeling & 0xf) << 24);
  191.     if (equippy_chars)        /* equippy chars option -CWS */
  192.     l |= 0x20000000L;
  193.     if (quick_messages)        /* quick messages option -CWS */
  194.     l |= 0x40000000L;
  195.     if (death)
  196.     l |= 0x80000000L;    /* Sign bit */
  197.     wr_long(GROND);
  198.     wr_long(RINGIL);
  199.     wr_long(AEGLOS);
  200.     wr_long(ARUNRUTH);
  201.     wr_long(MORMEGIL);
  202.     wr_long(ANGRIST);
  203.     wr_long(GURTHANG);
  204.     wr_long(CALRIS);
  205.     wr_long(ANDURIL);
  206.     wr_long(STING);
  207.     wr_long(ORCRIST);
  208.     wr_long(GLAMDRING);
  209.     wr_long(DURIN);
  210.     wr_long(AULE);
  211.     wr_long(THUNDERFIST);
  212.     wr_long(BLOODSPIKE);
  213.     wr_long(DOOMCALLER);
  214.     wr_long(NARTHANC);
  215.     wr_long(NIMTHANC);
  216.     wr_long(DETHANC);
  217.     wr_long(GILETTAR);
  218.     wr_long(RILIA);
  219.     wr_long(BELANGIL);
  220.     wr_long(BALLI);
  221.     wr_long(LOTHARANG);
  222.     wr_long(FIRESTAR);
  223.     wr_long(ERIRIL);
  224.     wr_long(CUBRAGOL);
  225.     wr_long(BARD);
  226.     wr_long(COLLUIN);
  227.     wr_long(HOLCOLLETH);
  228.     wr_long(TOTILA);
  229.     wr_long(PAIN);
  230.     wr_long(ELVAGIL);
  231.     wr_long(AGLARANG);
  232.     wr_long(EORLINGAS);
  233.     wr_long(BARUKKHELED);
  234.     wr_long(WRATH);
  235.     wr_long(HARADEKKET);
  236.     wr_long(MUNDWINE);
  237.     wr_long(GONDRICAM);
  238.     wr_long(ZARCUTHRA);
  239.     wr_long(CARETH);
  240.     wr_long(FORASGIL);
  241.     wr_long(CRISDURIAN);
  242.     wr_long(COLANNON);
  243.     wr_long(HITHLOMIR);
  244.     wr_long(THALKETTOTH);
  245.     wr_long(ARVEDUI);
  246.     wr_long(THRANDUIL);
  247.     wr_long(THENGEL);
  248.     wr_long(HAMMERHAND);
  249.     wr_long(CELEGORM);
  250.     wr_long(THROR);
  251.     wr_long(MAEDHROS);
  252.     wr_long(OLORIN);
  253.     wr_long(ANGUIREL);
  254.     wr_long(OROME);
  255.     wr_long(EONWE);
  256.     wr_long(THEODEN);
  257.     wr_long(ULMO);
  258.     wr_long(OSONDIR);
  259.     wr_long(TURMIL);
  260.     wr_long(CASPANION);
  261.     wr_long(TIL);
  262.     wr_long(DEATHWREAKER);
  263.     wr_long(AVAVIR);
  264.     wr_long(TARATOL);
  265.  
  266.     wr_long(DOR_LOMIN);
  267.     wr_long(NENYA);
  268.     wr_long(NARYA);
  269.     wr_long(VILYA);
  270.     wr_long(BELEGENNON);
  271.     wr_long(FEANOR);
  272.     wr_long(ISILDUR);
  273.     wr_long(SOULKEEPER);
  274.     wr_long(FINGOLFIN);
  275.     wr_long(ANARION);
  276.     wr_long(POWER);
  277.     wr_long(PHIAL);
  278.     wr_long(BELEG);
  279.     wr_long(DAL);
  280.     wr_long(PAURHACH);
  281.     wr_long(PAURNIMMEN);
  282.     wr_long(PAURAEGEN);
  283.     wr_long(PAURNEN);
  284.     wr_long(CAMMITHRIM);
  285.     wr_long(CAMBELEG);
  286.     wr_long(INGWE);
  287.     wr_long(CARLAMMAS);
  288.     wr_long(HOLHENNETH);
  289.     wr_long(AEGLIN);
  290.     wr_long(CAMLOST);
  291.     wr_long(NIMLOTH);
  292.     wr_long(NAR);
  293.     wr_long(BERUTHIEL);
  294.     wr_long(GORLIM);
  295.     wr_long(ELENDIL);
  296.     wr_long(THORIN);
  297.     wr_long(CELEBORN);
  298.     wr_long(THRAIN);
  299.     wr_long(GONDOR);
  300.     wr_long(THINGOL);
  301.     wr_long(THORONGIL);
  302.     wr_long(LUTHIEN);
  303.     wr_long(TUOR);
  304.     wr_long(ROHAN);
  305.     wr_long(TULKAS);
  306.     wr_long(NECKLACE);
  307.     wr_long(BARAHIR);
  308.     wr_long(RAZORBACK);
  309.     wr_long(BLADETURNER);
  310.  
  311.     for (i = 0; i < MAX_QUESTS; i++)
  312.     wr_long(quests[i]);
  313.  
  314.     for (i = 0; i < MAX_CREATURES; i++)
  315.     wr_unique(&u_list[i]);
  316.  
  317.     for (i = 0; i < MAX_CREATURES; i++) {
  318.     r_ptr = &c_recall[i];
  319.     if (r_ptr->r_cmove || r_ptr->r_cdefense || r_ptr->r_kills ||
  320.         r_ptr->r_spells2 || r_ptr->r_spells3 || r_ptr->r_spells ||
  321.         r_ptr->r_deaths || r_ptr->r_attacks[0] || r_ptr->r_attacks[1] ||
  322.         r_ptr->r_attacks[2] || r_ptr->r_attacks[3]) {
  323.         wr_short((int16u) i);
  324.         wr_long(r_ptr->r_cmove);
  325.         wr_long(r_ptr->r_spells);
  326.         wr_long(r_ptr->r_spells2);
  327.         wr_long(r_ptr->r_spells3);
  328.         wr_short(r_ptr->r_kills);
  329.         wr_short(r_ptr->r_deaths);
  330.         wr_long(r_ptr->r_cdefense);
  331.         wr_byte(r_ptr->r_wake);
  332.         wr_byte(r_ptr->r_ignore);
  333.         wr_bytes(r_ptr->r_attacks, MAX_MON_NATTACK);
  334.     }
  335.     }
  336.     wr_short((int16u) 0xFFFF);       /* sentinel to indicate no more monster info */
  337.  
  338.     wr_short((int16u) log_index);
  339.     wr_long(l);
  340.     wr_long(l);    /* added some duplicates, for future flags expansion -CWS */
  341.     wr_long(l);
  342.     wr_long(l);
  343.  
  344.     m_ptr = &py.misc;
  345.     wr_string(m_ptr->name);
  346.     wr_byte(m_ptr->male);
  347.     wr_long((int32u) m_ptr->au);
  348.     wr_long((int32u) m_ptr->max_exp);
  349.     wr_long((int32u) m_ptr->exp);
  350.     wr_short(m_ptr->exp_frac);
  351.     wr_short(m_ptr->age);
  352.     wr_short(m_ptr->ht);
  353.     wr_short(m_ptr->wt);
  354.     wr_short(m_ptr->lev);
  355.     wr_short(m_ptr->max_dlv);
  356.     wr_short((int16u) m_ptr->srh);
  357.     wr_short((int16u) m_ptr->fos);
  358.     wr_short((int16u) m_ptr->bth);
  359.     wr_short((int16u) m_ptr->bthb);
  360.     wr_short((int16u) m_ptr->mana);
  361.     wr_short((int16u) m_ptr->mhp);
  362.     wr_short((int16u) m_ptr->ptohit);
  363.     wr_short((int16u) m_ptr->ptodam);
  364.     wr_short((int16u) m_ptr->pac);
  365.     wr_short((int16u) m_ptr->ptoac);
  366.     wr_short((int16u) m_ptr->dis_th);
  367.     wr_short((int16u) m_ptr->dis_td);
  368.     wr_short((int16u) m_ptr->dis_ac);
  369.     wr_short((int16u) m_ptr->dis_tac);
  370.     wr_short((int16u) m_ptr->disarm);
  371.     wr_short((int16u) m_ptr->save);
  372.     wr_short((int16u) m_ptr->sc);
  373.     wr_short((int16u) m_ptr->stl);
  374.     wr_byte(m_ptr->pclass);
  375.     wr_byte(m_ptr->prace);
  376.     wr_byte(m_ptr->hitdie);
  377.     wr_byte(m_ptr->expfact);
  378.     wr_short((int16u) m_ptr->cmana);
  379.     wr_short(m_ptr->cmana_frac);
  380.     wr_short((int16u) m_ptr->chp);
  381.     wr_short(m_ptr->chp_frac);
  382.     for (i = 0; i < 4; i++)
  383.     wr_string(m_ptr->history[i]);
  384.  
  385.     s_ptr = &py.stats;
  386.     wr_shorts(s_ptr->max_stat, 6);
  387.     wr_bytes(s_ptr->cur_stat, 6);               /* Was wr_shorts -TL */
  388.     wr_shorts((int16u *) s_ptr->mod_stat, 6);
  389.     wr_shorts(s_ptr->use_stat, 6);
  390.  
  391.     f_ptr = &py.flags;
  392.     wr_long(f_ptr->status);
  393.     wr_short((int16u) f_ptr->rest);
  394.     wr_short((int16u) f_ptr->blind);
  395.     wr_short((int16u) f_ptr->paralysis);
  396.     wr_short((int16u) f_ptr->confused);
  397.     wr_short((int16u) f_ptr->food);
  398.     wr_short((int16u) f_ptr->food_digested);
  399.     wr_short((int16u) f_ptr->protection);
  400.     wr_short((int16u) f_ptr->speed);
  401.     wr_short((int16u) f_ptr->fast);
  402.     wr_short((int16u) f_ptr->slow);
  403.     wr_short((int16u) f_ptr->afraid);
  404.     wr_short((int16u) f_ptr->cut);
  405.     wr_short((int16u) f_ptr->stun);
  406.     wr_short((int16u) f_ptr->poisoned);
  407.     wr_short((int16u) f_ptr->image);
  408.     wr_short((int16u) f_ptr->protevil);
  409.     wr_short((int16u) f_ptr->invuln);
  410.     wr_short((int16u) f_ptr->hero);
  411.     wr_short((int16u) f_ptr->shero);
  412.     wr_short((int16u) f_ptr->shield);
  413.     wr_short((int16u) f_ptr->blessed);
  414.     wr_short((int16u) f_ptr->resist_heat);
  415.     wr_short((int16u) f_ptr->resist_cold);
  416.     wr_short((int16u) f_ptr->resist_acid);
  417.     wr_short((int16u) f_ptr->resist_light);
  418.     wr_short((int16u) f_ptr->resist_poison);
  419.     wr_short((int16u) f_ptr->detect_inv);
  420.     wr_short((int16u) f_ptr->word_recall);
  421.     wr_short((int16u) f_ptr->see_infra);
  422.     wr_short((int16u) f_ptr->tim_infra);
  423.     wr_byte(f_ptr->see_inv);
  424.     wr_byte(f_ptr->teleport);
  425.     wr_byte(f_ptr->free_act);
  426.     wr_byte(f_ptr->slow_digest);
  427.     wr_byte(f_ptr->aggravate);
  428.     wr_byte(f_ptr->fire_resist);
  429.     wr_byte(f_ptr->cold_resist);
  430.     wr_byte(f_ptr->acid_resist);
  431.     wr_byte(f_ptr->regenerate);
  432.     wr_byte(f_ptr->lght_resist);
  433.     wr_byte(f_ptr->ffall);
  434.     wr_byte(f_ptr->sustain_str);
  435.     wr_byte(f_ptr->sustain_int);
  436.     wr_byte(f_ptr->sustain_wis);
  437.     wr_byte(f_ptr->sustain_con);
  438.     wr_byte(f_ptr->sustain_dex);
  439.     wr_byte(f_ptr->sustain_chr);
  440.     wr_byte(f_ptr->confuse_monster);
  441.     wr_byte(f_ptr->new_spells);
  442.     wr_byte(f_ptr->poison_resist);
  443.     wr_byte(f_ptr->hold_life);
  444.     wr_byte(f_ptr->telepathy);
  445.     wr_byte(f_ptr->fire_im);
  446.     wr_byte(f_ptr->acid_im);
  447.     wr_byte(f_ptr->poison_im);
  448.     wr_byte(f_ptr->cold_im);
  449.     wr_byte(f_ptr->light_im);
  450.     wr_byte(f_ptr->light);
  451.     wr_byte(f_ptr->confusion_resist);
  452.     wr_byte(f_ptr->sound_resist);
  453.     wr_byte(f_ptr->light_resist);
  454.     wr_byte(f_ptr->dark_resist);
  455.     wr_byte(f_ptr->chaos_resist);
  456.     wr_byte(f_ptr->disenchant_resist);
  457.     wr_byte(f_ptr->shards_resist);
  458.     wr_byte(f_ptr->nexus_resist);
  459.     wr_byte(f_ptr->blindness_resist);
  460.     wr_byte(f_ptr->nether_resist);
  461.     wr_byte(f_ptr->fear_resist); /* added -CWS */
  462.  
  463.     wr_short((int16u) missile_ctr);
  464.     wr_long((int32u) turn);
  465.     wr_long((int32u) old_turn);    /* added -CWS */
  466.     wr_short((int16u) inven_ctr);
  467.     for (i = 0; i < inven_ctr; i++)
  468.     wr_item(&inventory[i]);
  469.     for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++)
  470.     wr_item(&inventory[i]);
  471.     wr_short((int16u) inven_weight);
  472.     wr_short((int16u) equip_ctr);
  473.     wr_long(spell_learned);
  474.     wr_long(spell_worked);
  475.     wr_long(spell_forgotten);
  476.     wr_long(spell_learned2);
  477.     wr_long(spell_worked2);
  478.     wr_long(spell_forgotten2);
  479.     wr_bytes(spell_order, 64);
  480.     wr_bytes(object_ident, OBJECT_IDENT_SIZE);
  481.     wr_long(randes_seed);
  482.     wr_long(town_seed);
  483.     wr_short((int16u) last_msg);
  484.     for (i = 0; i < MAX_SAVE_MSG; i++)
  485.     wr_string(old_msg[i]);
  486.  
  487. /* this indicates 'cheating' if it is a one */
  488.     wr_short((int16u) panic_save);
  489.     wr_short((int16u) total_winner);
  490.     wr_short((int16u) noscore);
  491.     wr_shorts(player_hp, MAX_PLAYER_LEVEL);
  492.  
  493.  
  494.     for (i = 0; i < MAX_STORES; i++) {
  495.     st_ptr = &store[i];
  496.     wr_long((int32u) st_ptr->store_open);
  497.     wr_short((int16u) st_ptr->insult_cur);
  498.     wr_byte(st_ptr->owner);
  499.     wr_byte(st_ptr->store_ctr);
  500.     wr_short(st_ptr->good_buy);
  501.     wr_short(st_ptr->bad_buy);
  502.  
  503.     for (j = 0; j < st_ptr->store_ctr; j++) {
  504.         wr_long((int32u) st_ptr->store_inven[j].scost);
  505.         wr_item(&st_ptr->store_inven[j].sitem);
  506.     }
  507.     }
  508.  
  509. /* save the current time in the savefile */
  510.     l = time((long *)0);
  511.  
  512. /* if (l < start_time) { someone is messing with the clock!, assume that we
  513.  * have been playing for 1 day l = start_time + 86400L; } 
  514.  */
  515.     wr_long(l);
  516.  
  517. /* starting with 5.2, put died_from string in savefile */
  518.     wr_string(died_from);
  519.  
  520. /* only level specific info follows, this allows characters to be
  521.  * resurrected, the dungeon level info is not needed for a resurrection 
  522.  */
  523.     if (death) {
  524.     if (ferror(fileptr) || fflush(fileptr) == EOF)
  525.         return FALSE;
  526.     return TRUE;
  527.     }
  528.     wr_short((int16u) dun_level);
  529.     wr_short((int16u) char_row);
  530.     wr_short((int16u) char_col);
  531.     wr_short((int16u) mon_tot_mult);
  532.     wr_short((int16u) cur_height);
  533.     wr_short((int16u) cur_width);
  534.     wr_short((int16u) max_panel_rows);
  535.     wr_short((int16u) max_panel_cols);
  536.  
  537.     for (i = 0; i < MAX_HEIGHT; i++)
  538.     for (j = 0; j < MAX_WIDTH; j++) {
  539.         c_ptr = &cave[i][j];
  540.         if (c_ptr->cptr != 0) {
  541.         wr_byte((int8u) i);
  542.         wr_byte((int8u) j);
  543.         wr_short((int16u) c_ptr->cptr); /* was wr_byte -CWS */
  544.         }
  545.     }
  546.     wr_byte((int8u) 0xFF);       /* marks end of cptr info */
  547.     for (i = 0; i < MAX_HEIGHT; i++)
  548.     for (j = 0; j < MAX_WIDTH; j++) {
  549.         c_ptr = &cave[i][j];
  550.         if (c_ptr->tptr != 0) {
  551.         wr_byte((int8u) i);
  552.         wr_byte((int8u) j);
  553.         wr_short((int16u) c_ptr->tptr);
  554.         }
  555.     }
  556.     wr_byte(0xFF);           /* marks end of tptr info */
  557.  
  558. /* must set counter to zero, note that code may write out two bytes
  559.  * unnecessarily 
  560.  */
  561.     count = 0;
  562.     prev_char = 0;
  563.     for (i = 0; i < MAX_HEIGHT; i++)
  564.     for (j = 0; j < MAX_WIDTH; j++) {
  565.         c_ptr = &cave[i][j];
  566.         char_tmp = c_ptr->fval | (c_ptr->lr << 4) | (c_ptr->fm << 5) |
  567.         (c_ptr->pl << 6) | (c_ptr->tl << 7);
  568.         if (char_tmp != prev_char || count == MAX_UCHAR) {
  569.         wr_byte((int8u) count);
  570.         wr_byte(prev_char);
  571.         prev_char = char_tmp;
  572.         count = 1;
  573.         } else
  574.         count++;
  575.     }
  576. /* save last entry */
  577.     wr_byte((int8u) count);
  578.     wr_byte(prev_char);
  579.  
  580. #ifdef MSDOS
  581.  
  582. /* must change graphics symbols for walls and floors back to default chars,
  583.  * this is necessary so that if the user changes the graphics line, the
  584.  * program will be able change all existing walls/floors to the new symbol 
  585.  */
  586.     t_ptr = &t_list[tcptr - 1];
  587.     for (i = tcptr - 1; i >= MIN_TRIX; i--) {
  588.     if (t_ptr->tchar == wallsym)
  589.         t_ptr->tchar = '#';
  590.     t_ptr--;
  591.     }
  592. #endif
  593.     wr_short((int16u) tcptr);
  594.     for (i = MIN_TRIX; i < tcptr; i++)
  595.     wr_item(&t_list[i]);
  596.     wr_short((int16u) mfptr);
  597.     for (i = MIN_MONIX; i < mfptr; i++)
  598.     wr_monster(&m_list[i]);
  599.  
  600. /* Save ghost names & stats etc... */
  601.      if (!c_list[MAX_CREATURES - 1].name) {
  602.                                   /* Can't dereference NULL! */
  603.      c_list[MAX_CREATURES - 1].name = (char*)malloc(101);
  604.      bzero((char *)c_list[MAX_CREATURES - 1].name, 101);
  605.      }
  606.     wr_bytes(c_list[MAX_CREATURES - 1].name, 100);
  607.     wr_long((int32u) c_list[MAX_CREATURES - 1].cmove);
  608.     wr_long((int32u) c_list[MAX_CREATURES - 1].spells);
  609.     wr_long((int32u) c_list[MAX_CREATURES - 1].cdefense);
  610.     {
  611.     int16u temp;
  612. /* fix player ghost's exp bug.  The mexp field is really an int32u, but the
  613.  * savefile was writing/reading an int16u.  Since I don't want to change
  614.  * the savefile format, this insures that the low bits of mexp are written (No
  615.  * ghost should be worth more than 64K (Melkor is only worth 60k!), but we
  616.  * check anyway).  Using temp insures that the low bits are all written, and works
  617.  * perfectly with a similar fix when* loading a character. -CFT
  618.  */
  619.  
  620.     if (c_list[MAX_CREATURES - 1].mexp > (int32u) 0xff00)
  621.         temp = (int16u) 0xff00;
  622.     else
  623.         temp = (int16u) c_list[MAX_CREATURES - 1].mexp;
  624.     wr_short((int16u) temp);
  625.     }
  626.     wr_short((int8u) c_list[MAX_CREATURES - 1].sleep);
  627.     wr_byte((int8u) c_list[MAX_CREATURES - 1].aaf);
  628.     wr_short((int8u) c_list[MAX_CREATURES - 1].ac);
  629.     wr_byte((int8u) c_list[MAX_CREATURES - 1].speed);
  630.     wr_byte((int8u) c_list[MAX_CREATURES - 1].cchar);
  631.     wr_bytes(c_list[MAX_CREATURES - 1].hd, 2);
  632.     wr_bytes(c_list[MAX_CREATURES - 1].damage, sizeof(attid) * 4);
  633.     wr_short((int16u) c_list[MAX_CREATURES - 1].level);
  634.  
  635.     if (ferror(fileptr) || (fflush(fileptr) == EOF))
  636.     return FALSE;
  637.     return TRUE;
  638. }
  639.  
  640. int 
  641. save_char()
  642. {
  643.     vtype temp;
  644.     char *tmp2;
  645.  
  646. #ifdef SECURE
  647.     beGames();
  648. #endif
  649.     if (death && NO_SAVE)
  650.     return TRUE;
  651.  
  652.     if (_save_char(savefile)) {
  653.  
  654.     tmp2 = basename(savefile);
  655.  
  656.     (void)sprintf(temp, "%s/p.%s", ANGBAND_SAV, (tmp2 + 1));
  657.  
  658.     unlink(temp);
  659.     } else {
  660.     return FALSE;
  661.     }
  662. #ifdef SECURE
  663.     bePlayer();
  664. #endif
  665.     return TRUE;
  666. }
  667.  
  668. int 
  669. _save_char(fnam)
  670. char *fnam;
  671. {
  672.     vtype temp;
  673.     int   ok, fd;
  674.     int8u char_tmp;
  675.  
  676.     if (log_index < 0)
  677.     return TRUE;           /* Nothing to save. */
  678.  
  679.     nosignals();
  680.     put_qio();
  681.     disturb(1, 0);           /* Turn off resting and searching. */
  682.     change_speed(-pack_heavy);       /* Fix the speed */
  683.     pack_heavy = 0;
  684.     ok = FALSE;
  685. #ifndef ATARIST_MWC
  686.     fd = (-1);
  687.     fileptr = NULL;           /* Do not assume it has been init'ed */
  688. #ifdef SET_UID
  689.     fd = my_topen(fnam, O_RDWR | O_CREAT | O_EXCL, 0600);
  690. #else
  691.     fd = my_topen(fnam, O_RDWR | O_CREAT | O_EXCL, 0666);
  692. #endif
  693.     if (fd < 0 && access(fnam, 0) >= 0 &&
  694.     (from_savefile ||
  695.      (wizard && get_check("Can't make new savefile. Overwrite old?")))) {
  696. #ifdef SET_UID
  697.     (void)chmod(fnam, 0600);
  698.     fd = my_topen(fnam, O_RDWR | O_TRUNC, 0600);
  699. #else
  700.     (void)chmod(fnam, 0666);
  701.     fd = my_topen(fnam, O_RDWR | O_TRUNC, 0666);
  702. #endif
  703.     }
  704.     if (fd >= 0) {
  705.     (void)close(fd);
  706. #endif                   /* !ATARIST_MWC */
  707.     /* GCC for atari st defines atarist */
  708. #if defined(atarist) || defined(ATARIST_MWC) || defined(MSDOS) || defined(__MINT__)
  709.     fileptr = my_tfopen(savefile, "wb");
  710. #else
  711.     fileptr = my_tfopen(savefile, "w");
  712. #endif
  713. #ifndef ATARIST_MWC
  714.     }
  715. #endif
  716.     if (fileptr != NULL) {
  717. #ifdef MSDOS
  718.     (void)setmode(fileno(fileptr), O_BINARY);
  719. #endif
  720.     xor_byte = 0;
  721.     wr_byte((int8u) CUR_VERSION_MAJ);
  722.     xor_byte = 0;
  723.     wr_byte((int8u) CUR_VERSION_MIN);
  724.     xor_byte = 0;
  725.     wr_byte((int8u) PATCH_LEVEL);
  726.     xor_byte = 0;
  727.     char_tmp = randint(256) - 1;
  728.     wr_byte(char_tmp);
  729.     /* Note that xor_byte is now equal to char_tmp */
  730.  
  731.     ok = sv_write();
  732.     if (fclose(fileptr) == EOF)
  733.         ok = FALSE;
  734.     }
  735.     if (!ok) {
  736.     if (fd >= 0)
  737.         (void)unlink(fnam);
  738.     signals();
  739.     if (fd >= 0)
  740.         (void)sprintf(temp, "Error writing to savefile");
  741.     else
  742.     /* here? */
  743.         (void)sprintf(temp, "Can't create new savefile");
  744.     msg_print(temp);
  745.     return FALSE;
  746.     } else
  747.     character_saved = 1;
  748.  
  749.     turn = (-1);
  750.     log_index = (-1);
  751.  
  752.     signals();
  753.  
  754.     return TRUE;
  755. }
  756.  
  757.  
  758. /* Certain checks are ommitted for the wizard. -CJS- */
  759.  
  760. int 
  761. get_char(generate)
  762. int *generate;
  763. {
  764.     int                    i, j, fd, c, ok, total_count;
  765.     int32u                 l, age, time_saved;
  766.     vtype                  temp;
  767.     int16u                 int16u_tmp;
  768.     register cave_type    *c_ptr;
  769.     register recall_type  *r_ptr;
  770.     struct misc           *m_ptr;
  771.     struct stats          *s_ptr;
  772.     register struct flags *f_ptr;
  773.     store_type            *st_ptr;
  774.     int8u char_tmp, ychar, xchar, count;
  775.  
  776.     free_turn_flag = TRUE;       /* So a feeling isn't generated upon reloading -DGK */
  777.     nosignals();
  778.     *generate = TRUE;
  779.     fd = (-1);
  780.  
  781.     if (access(savefile, 0) < 0) {
  782.     signals();
  783.     msg_print("Savefile does not exist.");
  784.     return FALSE;
  785.     }
  786.     clear_screen();
  787.  
  788.     (void)sprintf(temp, "Restoring Character.");
  789.     put_buffer(temp, 23, 0);
  790.     sleep(1);
  791.  
  792.     if (turn >= 0)
  793.     msg_print("IMPOSSIBLE! Attempt to restore while still alive!");
  794.  
  795. /* Allow restoring a file belonging to someone else - if we can delete it. */
  796. /* Hence first try to read without doing a chmod. */
  797.  
  798.     else if ((fd = my_topen(savefile, O_RDONLY, 0)) < 0)
  799.     msg_print("Can't open file for reading.");
  800.     else {
  801. #ifndef SET_UID
  802.     struct stat         statbuf;
  803.  
  804. #endif
  805.     turn = (-1);
  806.     log_index = (-1);
  807.     ok = TRUE;
  808.  
  809. #ifndef SET_UID
  810.     (void)fstat(fd, &statbuf);
  811. #endif
  812.     (void)close(fd);
  813.     /* GCC for atari st defines atarist */
  814. #if defined(__MINT__) || defined(atarist) || defined(ATARIST_MWC) || defined(MSDOS)
  815.     fileptr = my_tfopen(savefile, "rb");
  816. #else
  817.     fileptr = my_tfopen(savefile, "r");
  818. #endif
  819.     if (fileptr == NULL)
  820.         goto error;
  821.  
  822.     prt("Restoring Memory...", 0, 0);
  823.     put_qio();
  824.  
  825.     xor_byte = 0;
  826.     rd_byte(&version_maj);
  827.     xor_byte = 0;
  828.     rd_byte(&version_min);
  829.     xor_byte = 0;
  830.     rd_byte(&patch_level);
  831.     xor_byte = 0;
  832.     rd_byte(&xor_byte);
  833.  
  834. /* This boneheadedness is a direct result of the fact that Angband 2.4
  835.  * had version constants of 5.2, not 2.4.  2.5 inherited this.  2.6 fixes
  836.  * the problem.  Note that there must never be a 5.2.x version of Angband,
  837.  * or else this code will get confused. -CWS
  838.  */
  839.     if ((version_maj == 5) && (version_min == 2)) {
  840.       version_maj = 2;
  841.       version_min = 5;
  842.     }
  843.  
  844.     if ((version_maj != CUR_VERSION_MAJ)
  845.         || (version_min > CUR_VERSION_MIN)
  846.         || (version_min == CUR_VERSION_MIN && patch_level > PATCH_LEVEL)) {
  847.         prt("Sorry. This savefile is from a different version of Angband.",
  848.         2, 0);
  849.         goto error;
  850.     }
  851.     put_qio();
  852.     rd_long(&GROND);
  853.     rd_long(&RINGIL);
  854.     rd_long(&AEGLOS);
  855.     rd_long(&ARUNRUTH);
  856.     rd_long(&MORMEGIL);
  857.     rd_long(&ANGRIST);
  858.     rd_long(&GURTHANG);
  859.     rd_long(&CALRIS);
  860.     rd_long(&ANDURIL);
  861.     rd_long(&STING);
  862.     rd_long(&ORCRIST);
  863.     rd_long(&GLAMDRING);
  864.     rd_long(&DURIN);
  865.     rd_long(&AULE);
  866.     rd_long(&THUNDERFIST);
  867.     rd_long(&BLOODSPIKE);
  868.     rd_long(&DOOMCALLER);
  869.     rd_long(&NARTHANC);
  870.     rd_long(&NIMTHANC);
  871.     rd_long(&DETHANC);
  872.     rd_long(&GILETTAR);
  873.     rd_long(&RILIA);
  874.     rd_long(&BELANGIL);
  875.     rd_long(&BALLI);
  876.     rd_long(&LOTHARANG);
  877.     rd_long(&FIRESTAR);
  878.     rd_long(&ERIRIL);
  879.     rd_long(&CUBRAGOL);
  880.     rd_long(&BARD);
  881.     rd_long(&COLLUIN);
  882.     rd_long(&HOLCOLLETH);
  883.     rd_long(&TOTILA);
  884.     rd_long(&PAIN);
  885.     rd_long(&ELVAGIL);
  886.     rd_long(&AGLARANG);
  887.     rd_long(&EORLINGAS);
  888.     rd_long(&BARUKKHELED);
  889.     rd_long(&WRATH);
  890.     rd_long(&HARADEKKET);
  891.     rd_long(&MUNDWINE);
  892.     rd_long(&GONDRICAM);
  893.     rd_long(&ZARCUTHRA);
  894.     rd_long(&CARETH);
  895.     rd_long(&FORASGIL);
  896.     rd_long(&CRISDURIAN);
  897.     rd_long(&COLANNON);
  898.     rd_long(&HITHLOMIR);
  899.     rd_long(&THALKETTOTH);
  900.     rd_long(&ARVEDUI);
  901.     rd_long(&THRANDUIL);
  902.     rd_long(&THENGEL);
  903.     rd_long(&HAMMERHAND);
  904.     rd_long(&CELEGORM);
  905.     rd_long(&THROR);
  906.     rd_long(&MAEDHROS);
  907.     rd_long(&OLORIN);
  908.     rd_long(&ANGUIREL);
  909.     rd_long(&OROME);
  910.     rd_long(&EONWE);
  911.     rd_long(&THEODEN);
  912.     rd_long(&ULMO);
  913.     rd_long(&OSONDIR);
  914.     rd_long(&TURMIL);
  915.     rd_long(&CASPANION);
  916.     rd_long(&TIL);
  917.     rd_long(&DEATHWREAKER);
  918.     rd_long(&AVAVIR);
  919.     rd_long(&TARATOL);
  920.     if (to_be_wizard)
  921.         prt("Loaded Weapon Artifacts", 2, 0);
  922.     put_qio();
  923.  
  924.  
  925.     rd_long(&DOR_LOMIN);
  926.     rd_long(&NENYA);
  927.     rd_long(&NARYA);
  928.     rd_long(&VILYA);
  929.     rd_long(&BELEGENNON);
  930.     rd_long(&FEANOR);
  931.     rd_long(&ISILDUR);
  932.     rd_long(&SOULKEEPER);
  933.     rd_long(&FINGOLFIN);
  934.     rd_long(&ANARION);
  935.     rd_long(&POWER);
  936.     rd_long(&PHIAL);
  937.     rd_long(&BELEG);
  938.     rd_long(&DAL);
  939.     rd_long(&PAURHACH);
  940.     rd_long(&PAURNIMMEN);
  941.     rd_long(&PAURAEGEN);
  942.     rd_long(&PAURNEN);
  943.     rd_long(&CAMMITHRIM);
  944.     rd_long(&CAMBELEG);
  945.     rd_long(&INGWE);
  946.     rd_long(&CARLAMMAS);
  947.     rd_long(&HOLHENNETH);
  948.     rd_long(&AEGLIN);
  949.     rd_long(&CAMLOST);
  950.     rd_long(&NIMLOTH);
  951.     rd_long(&NAR);
  952.     rd_long(&BERUTHIEL);
  953.     rd_long(&GORLIM);
  954.     rd_long(&ELENDIL);
  955.     rd_long(&THORIN);
  956.     rd_long(&CELEBORN);
  957.     rd_long(&THRAIN);
  958.     rd_long(&GONDOR);
  959.     rd_long(&THINGOL);
  960.     rd_long(&THORONGIL);
  961.     rd_long(&LUTHIEN);
  962.     rd_long(&TUOR);
  963.     rd_long(&ROHAN);
  964.     rd_long(&TULKAS);
  965.     rd_long(&NECKLACE);
  966.     rd_long(&BARAHIR);
  967.     rd_long(&RAZORBACK);
  968.     rd_long(&BLADETURNER);
  969.     if (to_be_wizard)
  970.         prt("Loaded Armour Artifacts", 3, 0);
  971.     put_qio();
  972.  
  973.     for (i = 0; i < MAX_QUESTS; i++)
  974.         rd_long(&quests[i]);
  975.     if (to_be_wizard)
  976.         prt("Loaded Quests", 4, 0);
  977.  
  978.     for (i = 0; i < MAX_CREATURES; i++)
  979.         rd_unique(&u_list[i]);
  980.     if (to_be_wizard)
  981.         prt("Loaded Unique Beasts", 5, 0);
  982.     put_qio();
  983.  
  984.     rd_short(&int16u_tmp);
  985.     while (int16u_tmp != 0xFFFF) {
  986.         if (int16u_tmp >= MAX_CREATURES)
  987.         goto error;
  988.         r_ptr = &c_recall[int16u_tmp];
  989.         rd_long(&r_ptr->r_cmove);
  990.         rd_long(&r_ptr->r_spells);
  991.         rd_long(&r_ptr->r_spells2);
  992.         rd_long(&r_ptr->r_spells3);
  993.         rd_short(&r_ptr->r_kills);
  994.         rd_short(&r_ptr->r_deaths);
  995.         rd_long(&r_ptr->r_cdefense);
  996.         rd_byte(&r_ptr->r_wake);
  997.         rd_byte(&r_ptr->r_ignore);
  998.         rd_bytes(r_ptr->r_attacks, MAX_MON_NATTACK);
  999.         rd_short(&int16u_tmp);
  1000.     }
  1001.     if (to_be_wizard)
  1002.         prt("Loaded Recall Memory", 6, 0);
  1003.     put_qio();
  1004.     rd_short((int16u *) & log_index);
  1005.         rd_long(&l);
  1006.     if ((version_maj >= 2) && (version_min >= 6)) {
  1007.       rd_long(&l);
  1008.       rd_long(&l);
  1009.       rd_long(&l);
  1010.     }
  1011.  
  1012.     if (to_be_wizard)
  1013.         prt("Loaded Options Memory", 7, 0);
  1014.     put_qio();
  1015.  
  1016.     if (l & 1)
  1017.         find_cut = TRUE;
  1018.     else
  1019.         find_cut = FALSE;
  1020.     if (l & 2)
  1021.         find_examine = TRUE;
  1022.     else
  1023.         find_examine = FALSE;
  1024.     if (l & 4)
  1025.         find_prself = TRUE;
  1026.     else
  1027.         find_prself = FALSE;
  1028.     if (l & 8)
  1029.         find_bound = TRUE;
  1030.     else
  1031.         find_bound = FALSE;
  1032.     if (l & 16)
  1033.         prompt_carry_flag = TRUE;
  1034.     else
  1035.         prompt_carry_flag = FALSE;
  1036.     if (l & 32)
  1037.         rogue_like_commands = TRUE;
  1038.     else
  1039.         rogue_like_commands = FALSE;
  1040.     if (l & 64)
  1041.         show_weight_flag = TRUE;
  1042.     else
  1043.         show_weight_flag = FALSE;
  1044.     if (l & 128)
  1045.         highlight_seams = TRUE;
  1046.     else
  1047.         highlight_seams = FALSE;
  1048.     if (l & 0x100L)
  1049.         find_ignore_doors = TRUE;
  1050.     else
  1051.         find_ignore_doors = FALSE;
  1052.     
  1053.     if (l & 0x200L)
  1054.         no_haggle_flag = TRUE;
  1055.     else
  1056.         no_haggle_flag = FALSE; 
  1057.     if (l & 0x400L)
  1058.         carry_query_flag = FALSE;
  1059.     else
  1060.         carry_query_flag = TRUE;
  1061.     if (l & 0x1000L)
  1062.         unfelt = TRUE;
  1063.     else
  1064.         unfelt = FALSE;
  1065.     delay_spd = ((l >> 13) & 0xf);
  1066.     if (delay_spd > 10)
  1067.         delay_spd = 10;       /* bounds check for delay_speed -CWS */
  1068.     if (delay_spd < 0)
  1069.         delay_spd = 0;
  1070.     hitpoint_warn = ((l >> 17) & 0xf);
  1071.     if (l & 0x00400000L)       /* don't do "black Mushroom of Curing" */
  1072.         plain_descriptions = TRUE;
  1073.     else
  1074.         plain_descriptions = FALSE;
  1075.     if (l & 0x00800000L)
  1076.         show_equip_weight_flag = TRUE;
  1077.     else
  1078.         show_equip_weight_flag = FALSE;
  1079.     feeling = ((l >> 24) & 0xf);
  1080.     if (feeling > 10)
  1081.         feeling = 0;        /* bounds for level feelings -CWS */
  1082.     if (feeling < 0)
  1083.         feeling = 0;
  1084.  
  1085.     if (l & 0x20000000L)
  1086.         equippy_chars = TRUE;   /* equippy chars option -CWS */
  1087.     else
  1088.         equippy_chars = FALSE;
  1089.  
  1090.     if (l & 0x40000000L)
  1091.         quick_messages = TRUE;  /* quick messages option -CWS */
  1092.     else
  1093.         quick_messages = FALSE;
  1094.  
  1095.     if (to_be_wizard && (l & 0x80000000L)
  1096.         && get_check("Resurrect a dead character?"))
  1097.         l &= ~0x80000000L;
  1098.     if ((l & 0x80000000L) == 0) {
  1099.         m_ptr = &py.misc;
  1100.         rd_string(m_ptr->name);
  1101.         rd_byte(&m_ptr->male);
  1102.         rd_long((int32u *) & m_ptr->au);
  1103.         rd_long((int32u *) & m_ptr->max_exp);
  1104.         rd_long((int32u *) & m_ptr->exp);
  1105.         rd_short(&m_ptr->exp_frac);
  1106.         rd_short(&m_ptr->age);
  1107.         rd_short(&m_ptr->ht);
  1108.         rd_short(&m_ptr->wt);
  1109.         rd_short(&m_ptr->lev);
  1110.         rd_short(&m_ptr->max_dlv);
  1111.         rd_short((int16u *) & m_ptr->srh);
  1112.         rd_short((int16u *) & m_ptr->fos);
  1113.         rd_short((int16u *) & m_ptr->bth);
  1114.         rd_short((int16u *) & m_ptr->bthb);
  1115.         rd_short((int16u *) & m_ptr->mana);
  1116.         rd_short((int16u *) & m_ptr->mhp);
  1117.         rd_short((int16u *) & m_ptr->ptohit);
  1118.         rd_short((int16u *) & m_ptr->ptodam);
  1119.         rd_short((int16u *) & m_ptr->pac);
  1120.         rd_short((int16u *) & m_ptr->ptoac);
  1121.         rd_short((int16u *) & m_ptr->dis_th);
  1122.         rd_short((int16u *) & m_ptr->dis_td);
  1123.         rd_short((int16u *) & m_ptr->dis_ac);
  1124.         rd_short((int16u *) & m_ptr->dis_tac);
  1125.         rd_short((int16u *) & m_ptr->disarm);
  1126.         rd_short((int16u *) & m_ptr->save);
  1127.         rd_short((int16u *) & m_ptr->sc);
  1128.         rd_short((int16u *) & m_ptr->stl);
  1129.         rd_byte(&m_ptr->pclass);
  1130.         rd_byte(&m_ptr->prace);
  1131.         rd_byte(&m_ptr->hitdie);
  1132.         rd_byte(&m_ptr->expfact);
  1133.         rd_short((int16u *) & m_ptr->cmana);
  1134.         rd_short(&m_ptr->cmana_frac);
  1135.         rd_short((int16u *) & m_ptr->chp);
  1136.         rd_short(&m_ptr->chp_frac);
  1137.         for (i = 0; i < 4; i++)
  1138.         rd_string(m_ptr->history[i]);
  1139.  
  1140.         s_ptr = &py.stats;
  1141.         rd_shorts(s_ptr->max_stat, 6);
  1142.         if (version_maj <= 2 && version_min <=5 && patch_level <= 6)
  1143.         rd_shorts(s_ptr->cur_stat, 6);
  1144.         else
  1145.         rd_bytes(s_ptr->cur_stat, 6);                   /* -TL */
  1146.         rd_shorts((int16u *) s_ptr->mod_stat, 6);
  1147.         rd_shorts(s_ptr->use_stat, 6);
  1148.  
  1149.         f_ptr = &py.flags;
  1150.         rd_long(&f_ptr->status);
  1151.         rd_short((int16u *) & f_ptr->rest);
  1152.         rd_short((int16u *) & f_ptr->blind);
  1153.         rd_short((int16u *) & f_ptr->paralysis);
  1154.         rd_short((int16u *) & f_ptr->confused);
  1155.         rd_short((int16u *) & f_ptr->food);
  1156.         rd_short((int16u *) & f_ptr->food_digested);
  1157.         rd_short((int16u *) & f_ptr->protection);
  1158.         rd_short((int16u *) & f_ptr->speed);
  1159.         rd_short((int16u *) & f_ptr->fast);
  1160.         rd_short((int16u *) & f_ptr->slow);
  1161.         rd_short((int16u *) & f_ptr->afraid);
  1162.         rd_short((int16u *) & f_ptr->cut);
  1163.         rd_short((int16u *) & f_ptr->stun);
  1164.         rd_short((int16u *) & f_ptr->poisoned);
  1165.         rd_short((int16u *) & f_ptr->image);
  1166.         rd_short((int16u *) & f_ptr->protevil);
  1167.         rd_short((int16u *) & f_ptr->invuln);
  1168.         rd_short((int16u *) & f_ptr->hero);
  1169.         rd_short((int16u *) & f_ptr->shero);
  1170.         rd_short((int16u *) & f_ptr->shield);
  1171.         rd_short((int16u *) & f_ptr->blessed);
  1172.         rd_short((int16u *) & f_ptr->resist_heat);
  1173.         rd_short((int16u *) & f_ptr->resist_cold);
  1174.         rd_short((int16u *) & f_ptr->resist_acid);
  1175.         rd_short((int16u *) & f_ptr->resist_light);
  1176.         rd_short((int16u *) & f_ptr->resist_poison);
  1177.         rd_short((int16u *) & f_ptr->detect_inv);
  1178.         rd_short((int16u *) & f_ptr->word_recall);
  1179.         rd_short((int16u *) & f_ptr->see_infra);
  1180.         rd_short((int16u *) & f_ptr->tim_infra);
  1181.         rd_byte(&f_ptr->see_inv);
  1182.         rd_byte(&f_ptr->teleport);
  1183.         rd_byte(&f_ptr->free_act);
  1184.         rd_byte(&f_ptr->slow_digest);
  1185.         rd_byte(&f_ptr->aggravate);
  1186.         rd_byte(&f_ptr->fire_resist);
  1187.         rd_byte(&f_ptr->cold_resist);
  1188.         rd_byte(&f_ptr->acid_resist);
  1189.         rd_byte(&f_ptr->regenerate);
  1190.         rd_byte(&f_ptr->lght_resist);
  1191.         rd_byte(&f_ptr->ffall);
  1192.         rd_byte(&f_ptr->sustain_str);
  1193.         rd_byte(&f_ptr->sustain_int);
  1194.         rd_byte(&f_ptr->sustain_wis);
  1195.         rd_byte(&f_ptr->sustain_con);
  1196.         rd_byte(&f_ptr->sustain_dex);
  1197.         rd_byte(&f_ptr->sustain_chr);
  1198.         rd_byte(&f_ptr->confuse_monster);
  1199.         rd_byte(&f_ptr->new_spells);
  1200.         rd_byte(&f_ptr->poison_resist);
  1201.         rd_byte(&f_ptr->hold_life);
  1202.         rd_byte(&f_ptr->telepathy);
  1203.         rd_byte(&f_ptr->fire_im);
  1204.         rd_byte(&f_ptr->acid_im);
  1205.         rd_byte(&f_ptr->poison_im);
  1206.         rd_byte(&f_ptr->cold_im);
  1207.         rd_byte(&f_ptr->light_im);
  1208.         rd_byte(&f_ptr->light);
  1209.         rd_byte(&f_ptr->confusion_resist);
  1210.         rd_byte(&f_ptr->sound_resist);
  1211.         rd_byte(&f_ptr->light_resist);
  1212.         rd_byte(&f_ptr->dark_resist);
  1213.         rd_byte(&f_ptr->chaos_resist);
  1214.         rd_byte(&f_ptr->disenchant_resist);
  1215.         rd_byte(&f_ptr->shards_resist);
  1216.         rd_byte(&f_ptr->nexus_resist);
  1217.         rd_byte(&f_ptr->blindness_resist);
  1218.         rd_byte(&f_ptr->nether_resist);
  1219.         if ((version_maj >= 2) && (version_min >= 6))
  1220.         rd_byte(&f_ptr->fear_resist);
  1221.         else
  1222.         f_ptr->fear_resist = 0;    /* sigh */
  1223.  
  1224.         rd_short((int16u *) & missile_ctr);
  1225.         rd_long((int32u *) & turn);
  1226.         if ((version_maj >= 2) && (version_min >= 6))
  1227.           rd_long((int32u *) & old_turn);
  1228.         else
  1229.           old_turn = turn;    /* best we can do... -CWS */
  1230.  
  1231.         rd_short((int16u *) & inven_ctr);
  1232.         if (inven_ctr > INVEN_WIELD) {
  1233.         prt("ERROR in inven_ctr", 8, 0);
  1234.         goto error;
  1235.         }
  1236.         for (i = 0; i < inven_ctr; i++)
  1237.         rd_item(&inventory[i]);
  1238.         for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++)
  1239.         rd_item(&inventory[i]);
  1240.         rd_short((int16u *) & inven_weight);
  1241.         rd_short((int16u *) & equip_ctr);
  1242.         rd_long(&spell_learned);
  1243.         rd_long(&spell_worked);
  1244.         rd_long(&spell_forgotten);
  1245.         rd_long(&spell_learned2);
  1246.         rd_long(&spell_worked2);
  1247.         rd_long(&spell_forgotten2);
  1248.         rd_bytes(spell_order, 64);
  1249.         rd_bytes(object_ident, OBJECT_IDENT_SIZE);
  1250.         rd_long(&randes_seed);
  1251.         rd_long(&town_seed);
  1252.         rd_short((int16u *) & last_msg);
  1253.         for (i = 0; i < MAX_SAVE_MSG; i++)
  1254.         rd_string(old_msg[i]);
  1255.  
  1256.         rd_short((int16u *) & panic_save);
  1257.         rd_short((int16u *) & total_winner);
  1258.         rd_short((int16u *) & noscore);
  1259.         rd_shorts(player_hp, MAX_PLAYER_LEVEL);
  1260.  
  1261.         for (i = 0; i < MAX_STORES; i++) {
  1262.           st_ptr = &store[i];
  1263.           rd_long((int32u *) & st_ptr->store_open);
  1264.           rd_short((int16u *) & st_ptr->insult_cur);
  1265.           rd_byte(&st_ptr->owner);
  1266.           rd_byte(&st_ptr->store_ctr);
  1267.           rd_short(&st_ptr->good_buy);
  1268.           rd_short(&st_ptr->bad_buy);
  1269.           if (st_ptr->store_ctr > STORE_INVEN_MAX) {
  1270.         prt("ERROR in store_ctr", 9, 0);
  1271.         goto error;
  1272.           }
  1273.           for (j = 0; j < st_ptr->store_ctr; j++) {
  1274.         rd_long((int32u *) & st_ptr->store_inven[j].scost);
  1275.         rd_item(&st_ptr->store_inven[j].sitem);
  1276.           }
  1277.         }
  1278.  
  1279.         rd_long(&time_saved);
  1280. #ifndef SET_UID
  1281. #ifndef ALLOW_FIDDLING
  1282.         if (!to_be_wizard) {
  1283.             if (time_saved > (statbuf.st_ctime + 100) ||
  1284.             time_saved < (statbuf.st_ctime - 100)) {
  1285.             prt("Fiddled save file", 10, 0);
  1286.             goto error;
  1287.             }
  1288.         }
  1289. #endif
  1290. #endif
  1291.         rd_string(died_from);
  1292.     }
  1293.     if ((c = getc(fileptr)) == EOF || (l & 0x80000000L)) {
  1294.         if ((l & 0x80000000L) == 0) {
  1295.         if (!to_be_wizard || turn < 0) {
  1296.             prt("ERROR in to_be_wizard", 10, 0);
  1297.             goto error;
  1298.         }
  1299.         prt("Attempting a resurrection!", 0, 0);
  1300.         if (py.misc.chp < 0) {
  1301.             py.misc.chp = 0;
  1302.             py.misc.chp_frac = 0;
  1303.         }
  1304.         /* don't let him starve to death immediately */
  1305.         if (py.flags.food < 5000)
  1306.             py.flags.food = 5000;
  1307.         cure_poison();
  1308.         cure_blindness();
  1309.         cure_confusion();
  1310.         remove_fear();
  1311.         if (py.flags.image > 0)
  1312.             py.flags.image = 0;
  1313.         if (py.flags.cut > 0)
  1314.             py.flags.cut = 0;
  1315.         if (py.flags.stun > 0) {
  1316.             if (py.flags.stun > 50) {
  1317.             py.misc.ptohit += 20;
  1318.             py.misc.ptodam += 20;
  1319.             } else {
  1320.             py.misc.ptohit += 5;
  1321.             py.misc.ptodam += 5;
  1322.             }
  1323.             py.flags.stun = 0;
  1324.         }
  1325.         if (py.flags.word_recall > 0)
  1326.             py.flags.word_recall = 0;
  1327.         dun_level = 0;       /* Resurrect on the town level. */
  1328.         character_generated = 1;
  1329.  
  1330.         /* set noscore to indicate a resurrection, and don't enter wizard mode */
  1331.         to_be_wizard = FALSE;
  1332.         noscore |= 0x1;
  1333.         } else {
  1334.         prt("Restoring Memory of a departed spirit...", 0, 0);
  1335.         turn = (-1);
  1336.         old_turn = (-1);
  1337.         }
  1338.         put_qio();
  1339.     /* The log_index of the previous incarnation is here if later version
  1340.      * want to use it. For now, throw it away and get a new log. 
  1341.      */
  1342.         log_index = (-1);
  1343.         goto closefiles;
  1344.     }
  1345.     if (ungetc(c, fileptr) == EOF) {
  1346.         prt("ERROR in ungetc", 11, 0);
  1347.         goto error;
  1348.     }
  1349.     prt("Restoring Character...", 0, 0);
  1350.     put_qio();
  1351.  
  1352.     /* only level specific info should follow, not present for dead characters */
  1353.  
  1354.     rd_short((int16u *) & dun_level);
  1355.     rd_short((int16u *) & char_row);
  1356.     rd_short((int16u *) & char_col);
  1357.     rd_short((int16u *) & mon_tot_mult);
  1358.     rd_short((int16u *) & cur_height);
  1359.     rd_short((int16u *) & cur_width);
  1360.     rd_short((int16u *) & max_panel_rows);
  1361.     rd_short((int16u *) & max_panel_cols);
  1362.  
  1363.     /* read in the creature ptr info */
  1364.     rd_byte(&char_tmp);
  1365.     while (char_tmp != 0xFF) {
  1366.         ychar = char_tmp;
  1367.         rd_byte(&xchar);
  1368.  
  1369.     /* let's correctly fix the invisible monster bug  -CWS */
  1370.         if ((version_maj >= 2) && (version_min >= 6)) {
  1371.         rd_short((int16u *) & int16u_tmp);
  1372.         cave[ychar][xchar].cptr = int16u_tmp;
  1373.         } else {
  1374.         rd_byte((int8u *) & char_tmp);
  1375.         cave[ychar][xchar].cptr = char_tmp;
  1376.         }
  1377.         if (xchar > MAX_WIDTH || ychar > MAX_HEIGHT) {
  1378.         vtype               t1;
  1379.  
  1380.         sprintf(t1,
  1381.               "Error in creature ptr info: x=%x, y=%x, char_tmp=%x",
  1382.             (unsigned) xchar, (unsigned) ychar, (unsigned) char_tmp);
  1383.         prt(t1, 11, 0);
  1384.         }
  1385.         rd_byte(&char_tmp);
  1386.     }
  1387.     /* read in the treasure ptr info */
  1388.     rd_byte(&char_tmp);
  1389.     while (char_tmp != 0xFF) {
  1390.         ychar = char_tmp;
  1391.         rd_byte(&xchar);
  1392.         rd_short((int16u *) & int16u_tmp);
  1393.         if (xchar > MAX_WIDTH || ychar > MAX_HEIGHT) {
  1394.         prt("Error in treasure pointer info", 12, 0);
  1395.         goto error;
  1396.         }
  1397.         cave[ychar][xchar].tptr = int16u_tmp;
  1398.         rd_byte(&char_tmp);
  1399.     }
  1400.     /* read in the rest of the cave info */
  1401.     c_ptr = &cave[0][0];
  1402.     total_count = 0;
  1403.     while (total_count != MAX_HEIGHT * MAX_WIDTH) {
  1404.         rd_byte(&count);
  1405.         rd_byte(&char_tmp);
  1406.         for (i = count; i > 0; i--) {
  1407. #ifndef ATARIST_MWC
  1408.         if (c_ptr >= &cave[MAX_HEIGHT][0]) {
  1409.             prt("ERROR in cave size", 13, 0);
  1410.             goto error;
  1411.         }
  1412. #endif
  1413.         c_ptr->fval = char_tmp & 0xF;
  1414.         c_ptr->lr = (char_tmp >> 4) & 0x1;
  1415.         c_ptr->fm = (char_tmp >> 5) & 0x1;
  1416.         c_ptr->pl = (char_tmp >> 6) & 0x1;
  1417.         c_ptr->tl = (char_tmp >> 7) & 0x1;
  1418.         c_ptr++;
  1419.         }
  1420.         total_count += count;
  1421.     }
  1422.  
  1423.     rd_short((int16u *) & tcptr);
  1424.     if (tcptr > MAX_TALLOC) {
  1425.         prt("ERROR in MAX_TALLOC", 14, 0);
  1426.         goto error;
  1427.     }
  1428.     for (i = MIN_TRIX; i < tcptr; i++)
  1429.         rd_item(&t_list[i]);
  1430.     rd_short((int16u *) & mfptr);
  1431.     if (mfptr > MAX_MALLOC) {
  1432.         prt("ERROR in MAX_MALLOC", 15, 0);
  1433.         goto error;
  1434.     }
  1435.     for (i = MIN_MONIX; i < mfptr; i++) {
  1436.         rd_monster(&m_list[i]);
  1437.     }
  1438. #ifdef MSDOS
  1439.     /* change walls and floors to graphic symbols */
  1440.     t_ptr = &t_list[tcptr - 1];
  1441.     for (i = tcptr - 1; i >= MIN_TRIX; i--) {
  1442.         if (t_ptr->tchar == '#')
  1443.         t_ptr->tchar = wallsym;
  1444.         t_ptr--;
  1445.     }
  1446. #endif
  1447.  
  1448.                 /* Restore ghost names & stats etc... */
  1449.                 /* Allocate storage for name */
  1450.     c_list[MAX_CREATURES - 1].name = (char*)malloc(101);
  1451.     bzero((char *)c_list[MAX_CREATURES - 1].name, 101);
  1452.     *((char *) c_list[MAX_CREATURES - 1].name) = 'A';
  1453.     rd_bytes((int8u *) (c_list[MAX_CREATURES - 1].name), 100);
  1454.     rd_long((int32u *) & (c_list[MAX_CREATURES - 1].cmove));
  1455.     rd_long((int32u *) & (c_list[MAX_CREATURES - 1].spells));
  1456.     rd_long((int32u *) & (c_list[MAX_CREATURES - 1].cdefense));
  1457.     {
  1458.         int16u t1;
  1459. /* fix player ghost's exp bug.  The mexp field is really an int32u, but the
  1460.  * savefile was writing/ reading an int16u.  Since I don't want to change
  1461.  * the savefile format, this insures that the mexp field is loaded, and that
  1462.  * the "high bits" of mexp do not contain garbage values which could mean that
  1463.  * player ghost are worth millions of exp. -CFT
  1464.  */
  1465.  
  1466.         rd_short((int16u *) & t1);
  1467.         c_list[MAX_CREATURES - 1].mexp = (int32u) t1;
  1468.     }
  1469.  
  1470. /* more stupid size bugs that would've never been needed if these variables
  1471.  * had been given enough space in the first place -CWS
  1472.  */
  1473.     if ((version_maj >= 2) && (version_min >= 6))
  1474.         rd_short((int16u *) & (c_list[MAX_CREATURES - 1].sleep));
  1475.     else
  1476.         rd_byte((int8u *) & (c_list[MAX_CREATURES - 1].sleep));
  1477.  
  1478.     rd_byte((int8u *) & (c_list[MAX_CREATURES - 1].aaf));
  1479.  
  1480.     if ((version_maj >= 2) && (version_min >= 6))
  1481.         rd_short((int16u *) & (c_list[MAX_CREATURES - 1].ac));
  1482.     else
  1483.         rd_byte((int8u *) & (c_list[MAX_CREATURES - 1].ac));
  1484.  
  1485.     rd_byte((int8u *) & (c_list[MAX_CREATURES - 1].speed));
  1486.     rd_byte((int8u *) & (c_list[MAX_CREATURES - 1].cchar));
  1487.  
  1488.     rd_bytes((int8u *) (c_list[MAX_CREATURES - 1].hd), 2);
  1489.  
  1490.     rd_bytes((int8u *) (c_list[MAX_CREATURES - 1].damage), sizeof(attid) * 4);
  1491.     rd_short((int16u *) & (c_list[MAX_CREATURES - 1].level));
  1492.     *generate = FALSE;       /* We have restored a cave - no need to generate. */
  1493.  
  1494.     if ((version_min == 1 && patch_level < 3)
  1495.         || (version_min == 0))
  1496.         for (i = 0; i < MAX_STORES; i++) {
  1497.         st_ptr = &store[i];
  1498.         rd_long((int32u *) & st_ptr->store_open);
  1499.         rd_short((int16u *) & st_ptr->insult_cur);
  1500.         rd_byte(&st_ptr->owner);
  1501.         rd_byte(&st_ptr->store_ctr);
  1502.         rd_short(&st_ptr->good_buy);
  1503.         rd_short(&st_ptr->bad_buy);
  1504.         if (st_ptr->store_ctr > STORE_INVEN_MAX) {
  1505.             prt("ERROR in STORE_INVEN_MAX", 16, 0);
  1506.             goto error;
  1507.         }
  1508.         for (j = 0; j < st_ptr->store_ctr; j++) {
  1509.             rd_long((int32u *) & st_ptr->store_inven[j].scost);
  1510.             rd_item(&st_ptr->store_inven[j].sitem);
  1511.         }
  1512.         }
  1513.  
  1514.     /* read the time that the file was saved */
  1515.     rd_long(&time_saved);
  1516.  
  1517.     if (ferror(fileptr)) {
  1518.         prt("FILE ERROR", 17, 0);
  1519.         goto error;
  1520.     }
  1521.     if (turn < 0) {
  1522.         prt("Error = turn < 0", 7, 0);
  1523.     error:
  1524.         ok = FALSE;           /* Assume bad data. */
  1525.     } else {
  1526.     /* don't overwrite the killed by string if character is dead */
  1527.         if (py.misc.chp >= 0)
  1528.         (void)strcpy(died_from, "(alive and well)");
  1529.         character_generated = 1;
  1530.     }
  1531.  
  1532. closefiles:
  1533.  
  1534.     if (fileptr != NULL) {
  1535.         if (fclose(fileptr) < 0)
  1536.         ok = FALSE;
  1537.     }
  1538.     if (fd >= 0)
  1539.         (void)close(fd);
  1540.  
  1541.     if (!ok)
  1542.         msg_print("Error during reading of file.");
  1543.     else if (turn >= 0 && !_new_log())
  1544.         msg_print("Can't log player in the log file.");
  1545.     else {
  1546.     /* let the user overwrite the old savefile when save/quit */
  1547.         from_savefile = 1;
  1548.  
  1549.         signals();
  1550.  
  1551.         if (turn >= 0) {       /* Only if a full restoration. */
  1552.         weapon_heavy = FALSE;
  1553.         pack_heavy = 0;
  1554.         check_strength();
  1555.  
  1556.         /* rotate store inventory, depending on how old the save file */
  1557.         /* is foreach day old (rounded up), call store_maint */
  1558.         /* calculate age in seconds */
  1559.         start_time = time((long *)0);
  1560.         /* check for reasonable values of time here ... */
  1561.         if (start_time < time_saved)
  1562.             age = 0;
  1563.         else
  1564.             age = start_time - time_saved;
  1565.  
  1566.         age = (age + 43200L) / 86400L;    /* age in days */
  1567.         if (age > 10)
  1568.             age = 10;       /* in case savefile is very old */
  1569.         for (i = 0; i < age; i++)
  1570.             store_maint();
  1571.         }
  1572.  
  1573. /* if (noscore) msg_print("This save file cannot be used to get on the score board."); */
  1574.  
  1575.         if (version_maj != CUR_VERSION_MAJ
  1576.         || version_min != CUR_VERSION_MIN) {
  1577.         (void)sprintf(temp,
  1578.             "Save file version %d.%d %s on game version %d.%d.",
  1579.                   version_maj, version_min,
  1580.                   version_maj == CUR_VERSION_MAJ
  1581.                   ? "accepted" : "very risky",
  1582.                   CUR_VERSION_MAJ, CUR_VERSION_MIN);
  1583.         msg_print(temp);
  1584.         }
  1585.         if (turn >= 0) {
  1586.         char               *tmp2;
  1587.  
  1588.         tmp2 = basename(savefile);
  1589.  
  1590.         (void)sprintf(temp, "%s/p.%s", ANGBAND_SAV, (tmp2 + 1));
  1591.  
  1592.         link(savefile, temp);
  1593.         unlink(savefile);
  1594.         return TRUE;
  1595.         } else {
  1596.         return FALSE;       /* Only restored options and monster memory. */
  1597.         }
  1598.     }
  1599.     }
  1600.     turn = (-1);
  1601.     log_index = (-1);
  1602.     prt("Please try again without that savefile.", 1, 0);
  1603.     signals();
  1604. #ifdef MAC
  1605.     *exit_flag = TRUE;
  1606. #else
  1607.     exit_game();
  1608. #endif
  1609.  
  1610.     return FALSE;           /* not reached, unless on mac */
  1611. }
  1612.  
  1613. static void 
  1614. wr_byte(c)
  1615. int8u c;
  1616. {
  1617.     xor_byte ^= c;
  1618.     (void)putc((int)xor_byte, fileptr);
  1619. }
  1620.  
  1621. static void 
  1622. wr_short(s)
  1623. int16u s;
  1624. {
  1625.     xor_byte ^= (s & 0xFF);
  1626.     (void)putc((int)xor_byte, fileptr);
  1627.     xor_byte ^= ((s >> 8) & 0xFF);
  1628.     (void)putc((int)xor_byte, fileptr);
  1629. }
  1630.  
  1631. static void 
  1632. wr_long(l)
  1633. register int32u l;
  1634. {
  1635.     xor_byte ^= (l & 0xFF);
  1636.     (void)putc((int)xor_byte, fileptr);
  1637.     xor_byte ^= ((l >> 8) & 0xFF);
  1638.     (void)putc((int)xor_byte, fileptr);
  1639.     xor_byte ^= ((l >> 16) & 0xFF);
  1640.     (void)putc((int)xor_byte, fileptr);
  1641.     xor_byte ^= ((l >> 24) & 0xFF);
  1642.     (void)putc((int)xor_byte, fileptr);
  1643. }
  1644.  
  1645. static void 
  1646. wr_bytes(c, count)
  1647. int8u       *c;
  1648. register int count;
  1649. {
  1650.     register int    i;
  1651.     register int8u *ptr;
  1652.  
  1653.     ptr = c;
  1654.     for (i = 0; i < count; i++) {
  1655.     xor_byte ^= *ptr++;
  1656.     (void)putc((int)xor_byte, fileptr);
  1657.     }
  1658. }
  1659.  
  1660. static void 
  1661. wr_string(str)
  1662. register char *str;
  1663. {
  1664.     while (*str != '\0') {
  1665.     xor_byte ^= *str++;
  1666.     (void)putc((int)xor_byte, fileptr);
  1667.     }
  1668.     xor_byte ^= *str;
  1669.     (void)putc((int)xor_byte, fileptr);
  1670. }
  1671.  
  1672. static void 
  1673. wr_shorts(s, count)
  1674. int16u      *s;
  1675. register int count;
  1676. {
  1677.     register int        i;
  1678.     register int16u    *sptr;
  1679.  
  1680.     sptr = s;
  1681.     for (i = 0; i < count; i++) {
  1682.     xor_byte ^= (*sptr & 0xFF);
  1683.     (void)putc((int)xor_byte, fileptr);
  1684.     xor_byte ^= ((*sptr++ >> 8) & 0xFF);
  1685.     (void)putc((int)xor_byte, fileptr);
  1686.     }
  1687. }
  1688.  
  1689. static void 
  1690. wr_item(item)
  1691. register inven_type *item;
  1692. {
  1693.     wr_short(item->index);
  1694.     wr_byte(item->name2);
  1695.     wr_string(item->inscrip);
  1696.     wr_long(item->flags);
  1697.     wr_byte(item->tval);
  1698.     wr_byte(item->tchar);
  1699.     wr_short((int16u) item->p1);
  1700.     wr_long((int32u) item->cost);
  1701.     wr_byte(item->subval);
  1702.     wr_byte(item->number);
  1703.     wr_short(item->weight);
  1704.     wr_short((int16u) item->tohit);
  1705.     wr_short((int16u) item->todam);
  1706.     wr_short((int16u) item->ac);
  1707.     wr_short((int16u) item->toac);
  1708.     wr_bytes(item->damage, 2);
  1709.     wr_byte(item->level);
  1710.     wr_byte(item->ident);
  1711.     wr_long(item->flags2);
  1712.     wr_short((int16u) item->timeout);
  1713. }
  1714.  
  1715. static void 
  1716. wr_monster(mon)
  1717. register monster_type *mon;
  1718. {
  1719.     wr_short((int16u) mon->hp);
  1720.     wr_short((int16u) mon->maxhp); /* added -CWS */
  1721.     wr_short((int16u) mon->csleep);
  1722.     wr_short((int16u) mon->cspeed);
  1723.     wr_short(mon->mptr);
  1724.     wr_byte(mon->fy);
  1725.     wr_byte(mon->fx);
  1726.     wr_byte(mon->cdis);
  1727.     wr_byte(mon->ml);
  1728.     wr_byte(mon->stunned);
  1729.     wr_byte(mon->confused);
  1730.     wr_byte(mon->monfear);    /* added -CWS */
  1731. }
  1732.  
  1733. static void 
  1734. rd_byte(ptr)
  1735. int8u *ptr;
  1736. {
  1737.     int8u c;
  1738.  
  1739.     c = getc(fileptr) & 0xFF;
  1740.     *ptr = c ^ xor_byte;
  1741.     xor_byte = c;
  1742. }
  1743.  
  1744. static void 
  1745. rd_short(ptr)
  1746. int16u *ptr;
  1747. {
  1748.     int8u  c;
  1749.     int16u s;
  1750.  
  1751.     c = (getc(fileptr) & 0xFF);
  1752.     s = c ^ xor_byte;
  1753.     xor_byte = (getc(fileptr) & 0xFF);
  1754.     s |= (int16u) (c ^ xor_byte) << 8;
  1755.     *ptr = s;
  1756. }
  1757.  
  1758. static void 
  1759. rd_long(ptr)
  1760. int32u *ptr;
  1761. {
  1762.     register int32u l;
  1763.     register int8u  c;
  1764.  
  1765.     c = (getc(fileptr) & 0xFF);
  1766.     l = c ^ xor_byte;
  1767.     xor_byte = (getc(fileptr) & 0xFF);
  1768.     l |= (int32u) (c ^ xor_byte) << 8;
  1769.     c = (getc(fileptr) & 0xFF);
  1770.     l |= (int32u) (c ^ xor_byte) << 16;
  1771.     xor_byte = (getc(fileptr) & 0xFF);
  1772.     l |= (int32u) (c ^ xor_byte) << 24;
  1773.     *ptr = l;
  1774. }
  1775.  
  1776. static void 
  1777. rd_bytes(ptr, count)
  1778. int8u *ptr;
  1779. int    count;
  1780. {
  1781.     int   i;
  1782.     int8u c, nc;
  1783.  
  1784.     for (i = 0; i < count; i++) {
  1785.     c = (getc(fileptr) & 0xFF);
  1786.     nc = c ^ xor_byte;
  1787.     *ptr = nc;
  1788.     ptr++;
  1789.     xor_byte = c;
  1790.     }
  1791. }
  1792.  
  1793. static void 
  1794. rd_string(str)
  1795. char *str;
  1796. {
  1797.     register int8u c;
  1798.  
  1799.     do {
  1800.     c = (getc(fileptr) & 0xFF);
  1801.     *str = c ^ xor_byte;
  1802.     xor_byte = c;
  1803.     }
  1804.     while (*str++ != '\0');
  1805. }
  1806.  
  1807. static void 
  1808. rd_shorts(ptr, count)
  1809. int16u      *ptr;
  1810. register int count;
  1811. {
  1812.     register int        i;
  1813.     register int16u    *sptr;
  1814.     register int16u     s;
  1815.     int8u               c;
  1816.  
  1817.     sptr = ptr;
  1818.     for (i = 0; i < count; i++) {
  1819.     c = (getc(fileptr) & 0xFF);
  1820.     s = c ^ xor_byte;
  1821.     xor_byte = (getc(fileptr) & 0xFF);
  1822.     s |= (int16u) (c ^ xor_byte) << 8;
  1823.     *sptr++ = s;
  1824.     }
  1825. }
  1826.  
  1827. static void 
  1828. rd_item(item)
  1829. register inven_type *item;
  1830. {
  1831.     rd_short(&item->index);
  1832.     rd_byte(&item->name2);
  1833.     rd_string(item->inscrip);
  1834.     rd_long(&item->flags);
  1835.     rd_byte(&item->tval);
  1836.     rd_byte(&item->tchar);
  1837.     rd_short((int16u *) & item->p1);
  1838.     rd_long((int32u *) & item->cost);
  1839.     rd_byte(&item->subval);
  1840.     rd_byte(&item->number);
  1841.     rd_short(&item->weight);
  1842.     rd_short((int16u *) & item->tohit);
  1843.     rd_short((int16u *) & item->todam);
  1844.     rd_short((int16u *) & item->ac);
  1845.     rd_short((int16u *) & item->toac);
  1846.     rd_bytes(item->damage, 2);
  1847.     rd_byte(&item->level);
  1848.     rd_byte(&item->ident);
  1849.     rd_long(&item->flags2);
  1850.     rd_short((int16u *) & item->timeout);
  1851. }
  1852.  
  1853. static void 
  1854. rd_monster(mon)
  1855. register monster_type *mon;
  1856. {
  1857.     rd_short((int16u *) & mon->hp);
  1858.     if ((version_maj >= 2) && (version_min >= 6))
  1859.     rd_short((int16u *) & mon->maxhp);
  1860.     else {
  1861.     /* let's fix the infamous monster heal bug -CWS */
  1862.     mon->maxhp = mon->hp;
  1863.     }
  1864.  
  1865.     rd_short((int16u *) & mon->csleep);
  1866.     rd_short((int16u *) & mon->cspeed);
  1867.     rd_short(&mon->mptr);
  1868.     rd_byte(&mon->fy);
  1869.     rd_byte(&mon->fx);
  1870.     rd_byte(&mon->cdis);
  1871.     rd_byte(&mon->ml);
  1872.     rd_byte(&mon->stunned);
  1873.     rd_byte(&mon->confused);
  1874.     if ((version_maj >= 2) && (version_min >= 6))
  1875.     rd_byte((int8u *) & mon->monfear);
  1876.     else
  1877.     mon->monfear = 0; /* this is not saved either -CWS */
  1878. }
  1879.